/*
 * AutoAnswer
 * Copyright (C) 2010 EverySoft
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 *   Copyright (C) 2010 Tedd Scofield
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package com.everysoft.autoanswer;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import com.android.internal.telephony.ITelephony;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnInfoListener;

public class AutoAnswerIntentService extends IntentService {

	public AutoAnswerIntentService() {
		super("AutoAnswerIntentService");
	}

	// Media player members use to play sound
	private MediaPlayer m_player;
	private OnPreparedListener m_prpareListener;
	private OnErrorListener m_errorListener;
	private OnCompletionListener m_compleatListener;
	
	// media recorder members use to capture sound
	
	private MediaRecorder m_recorder; 
	private android.media.MediaRecorder.OnErrorListener m_errorRecorderListener;
	private OnInfoListener m_infoRecorderListener;
	
	
	@Override
	protected void onHandleIntent(Intent intent) {
		Context context = getBaseContext();

		// Load preferences
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
		BluetoothHeadset bh = null;
		if (prefs.getBoolean("headset_only", false)) {
			bh = new BluetoothHeadset(this, null);
		}
		
		String path = "/mnt/sdcard/Piano Blues 1.mp3";
		if(m_player == null)
		{
			m_player = new MediaPlayer();	
			
			m_prpareListener = new OnPreparedListener() {
				
				@Override
				public void onPrepared(MediaPlayer mp) {
					// TODO Auto-generated method stub
					this.notify();
				}
			};
			
			m_errorListener = new OnErrorListener() {
				
				@Override
				public boolean onError(MediaPlayer mp, int what, int extra) {
					// TODO Auto-generated method stub
					
					HandleCloseMediaPlayer();
					return false;
				}
			};
			
			m_compleatListener = new OnCompletionListener() {
				
				@Override
				public void onCompletion(MediaPlayer mp) {
					// TODO Auto-generated method stub
					
					PrepareRecording();
					
					StartRecordingMessage();
				}
			};
		}
		File incomeMessage = new File(path);
		boolean isExist = incomeMessage.exists();
		if(isExist)
		{
			try {
				m_player.setDataSource(path);
			} catch (IllegalArgumentException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IllegalStateException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
			
			
			m_player.setOnPreparedListener(m_prpareListener);
			m_player.setOnErrorListener(m_errorListener);
			m_player.setOnCompletionListener(m_compleatListener);
			
			m_player.setDisplay(null);
			
			try {
				m_player.prepare();
			} catch (IllegalStateException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
			// Let the phone ring for a set delay
			try {
				Thread.sleep(Integer.parseInt(prefs.getString("delay", "2")) * 1000);
			} catch (InterruptedException e) {
				// We don't really care
			}
	
			// Check headset status right before picking up the call
			if (prefs.getBoolean("headset_only", false) && bh != null) {
				if (bh.getState() != BluetoothHeadset.STATE_CONNECTED) {
					bh.close();
					return;
				}
				bh.close();
			}
	
			// Make sure the phone is still ringing
			TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
			if (tm.getCallState() != TelephonyManager.CALL_STATE_RINGING) {
				return;
			}
	
			// Answer the phone
			try {
				answerPhoneAidl(context);
			}
			catch (Exception e) {
				e.printStackTrace();
				Log.d("AutoAnswer","Error trying to answer using telephony service.  Falling back to headset.");
				answerPhoneHeadsethook(context);
			}
	
			// Enable the speakerphone
			if (prefs.getBoolean("use_speakerphone", false)) {
				enableSpeakerPhone(context);
			}
		}
		return;
	}

	private void enableSpeakerPhone(Context context) {
		AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
		audioManager.setSpeakerphoneOn(true);
	}

	private void answerPhoneHeadsethook(Context context) {
		// Simulate a press of the headset button to pick up the call
		Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON);		
		buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
		context.sendOrderedBroadcast(buttonDown, "android.permission.CALL_PRIVILEGED");

		// froyo and beyond trigger on buttonUp instead of buttonDown
		Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);		
		buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
		context.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");
	}

	@SuppressWarnings("unchecked")
	private void answerPhoneAidl(Context context) throws Exception {
		// Set up communication with the telephony service (thanks to Tedd's Droid Tools!)
		TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		Class c = Class.forName(tm.getClass().getName());
		Method m = c.getDeclaredMethod("getITelephony");
		m.setAccessible(true);
		ITelephony telephonyService;
		telephonyService = (ITelephony)m.invoke(tm);
		
	//	m_prpareListener.wait();

		// Silence the ringer and answer the call!
		//telephonyService.silenceRinger();
		telephonyService.answerRingingCall();
		
		
		PlayMeassage();
	}
	
	private void HandleCloseMediaPlayer()
	{
		m_player.stop();
		m_player.release();
	}
	
	private void PlayMeassage()
	{
		try {
			m_player.start();
			
			
		} catch (Exception e) {
			// TODO: handle exception
			
			@SuppressWarnings("unused")
			String errorMsg = e.getMessage();
		}
		finally
		{
			HandleCloseMediaPlayer();			
		}
	}
	
	private void PrepareRecording()
	{
		m_recorder = new MediaRecorder();
		m_recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_DOWNLINK);
		m_recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
		m_recorder.setOutputFile("mnt\\sdcard\\temp");
		m_recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
		
		m_errorRecorderListener = new android.media.MediaRecorder.OnErrorListener() {
			
			@Override
			public void onError(MediaRecorder mr, int what, int extra) {
				// TODO Auto-generated method stub
				HandleCloseMediaRecorder();
			}
		};
		
		m_infoRecorderListener = new OnInfoListener() {
			
			@Override
			public void onInfo(MediaRecorder mr, int what, int extra) {
				// TODO Auto-generated method stub
				
			}
		};
		
		m_recorder.setOnErrorListener(m_errorRecorderListener);
		m_recorder.setOnInfoListener(m_infoRecorderListener);
		
		try {
			m_recorder.prepare();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

	private void StartRecordingMessage(){
		m_recorder.start();
	}
	
	private void HandleCloseMediaRecorder()
	{
		m_recorder.stop();
		m_recorder.release();
	}
}